package util;

import constant.ChildWindowConstant;
import constant.CodeConstant;
import constant.CodeFtlConstant;
import constant.Constant;
import constant.FreeMarkerConfig;
import entity.DataSourceModel;
import entity.DatabaseModel;
import entity.EntityFieldModel;
import entity.MakeEntityModel;
import entity.TableConditionModel;
import entity.TableFiledModel;
import entity.TableNameAndType;
import entity.TablesQueryModel;
import freemarker.template.Template;

import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.OutputStreamWriter;
import java.io.Writer;
import java.nio.charset.StandardCharsets;
import java.util.ArrayList;
import java.util.List;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * @ClassName CodeWriterUtil
 * @Author zrx
 * @Date 2020/8/4 11:54
 */
public class CodeWriterUtil {

	private static Template getTemplate(String ftlStr) throws IOException {
		Template template = FreeMarkerConfig.configuration.getTemplate(ftlStr);
		template.setEncoding(StandardCharsets.UTF_8.name());
		return template;
	}

	// 首字母大写 驼峰
	public static String captureName(String name) {
		StringBuilder result = new StringBuilder();
		if (name.contains(".")) {
			String[] nameArr = name.split("\\.");
			for (String str : nameArr) {
				if (str.length() > 1) {
					result.append(str.substring(0, 1).toUpperCase()).append(str.substring(1));
				} else {
					result.append(str.substring(0, 1).toUpperCase());
				}
			}
		} else if (name.contains("_")) {
			String[] nameArr = name.split("_");
			for (String str : nameArr) {
				if (str.length() > 1) {
					result.append(str.substring(0, 1).toUpperCase()).append(str.substring(1));
				} else {
					result.append(str.substring(0, 1).toUpperCase());
				}
			}
		} else if (name.contains("-")) {
			String[] nameArr = name.split("-");
			for (String str : nameArr) {
				if (str.length() > 1) {
					result.append(str.substring(0, 1).toUpperCase()).append(str.substring(1));
				} else {
					result.append(str.substring(0, 1).toUpperCase());
				}
			}
		} else {
			if (name.length() > 1) {
				result = new StringBuilder(name.substring(0, 1).toUpperCase() + name.substring(1));
			} else {
				result = new StringBuilder(name.substring(0, 1).toUpperCase());
			}
		}
		return result.toString();
	}

	// 首字母小写
	public static String firstLower(String name) {
		String result;
		if (name.length() > 1) {
			result = name.substring(0, 1).toLowerCase() + name.substring(1);
		} else {
			result = name.substring(0, 1).toLowerCase();
		}
		return result;
	}

	/**
	 * 登录用户设置
	 *
	 * @param loginModel
	 * @param root
	 */
	public static void setLonginUser(String loginModel, Map<String, Object> root) {

		if ("静态用户".equals(loginModel)) {
			String condition = "";
			if (ChildWindowConstant.user1.size() != 0) {
				condition += "(\"" + ChildWindowConstant.user1.get(0) + "\"" + ".equals(user.getUserName()) && " + "\""
						+ ChildWindowConstant.user1.get(1) + "\"" + ".equals(user.getPassword()))" + " || ";
			}
			if (ChildWindowConstant.user2.size() != 0) {
				condition += "(\"" + ChildWindowConstant.user2.get(0) + "\"" + ".equals(user.getUserName()) && " + "\""
						+ ChildWindowConstant.user2.get(1) + "\"" + ".equals(user.getPassword()))" + " || ";
			}
			if (ChildWindowConstant.user3.size() != 0) {
				condition += "(\"" + ChildWindowConstant.user3.get(0) + "\"" + ".equals(user.getUserName()) && " + "\""
						+ ChildWindowConstant.user3.get(1) + "\"" + ".equals(user.getPassword()))" + " || ";
			}
			condition = condition.substring(0, condition.lastIndexOf("|") - 2);
			root.put(CodeConstant.USER_CONDITION, condition);
			root.put(CodeConstant.USER_NAME_FILED, "userName");
			root.put(CodeConstant.USER_PWD_FILED, "password");
		} else if ("动态用户".equals(loginModel)) {
			root.put(CodeConstant.USER_TABLE, ChildWindowConstant.dynamicUserList.get(0));
			root.put(CodeConstant.USER_NAME_FILED, ChildWindowConstant.dynamicUserList.get(1));
			root.put(CodeConstant.USER_PWD_FILED, ChildWindowConstant.dynamicUserList.get(2));
		}
	}

	/**
	 * 自定义实体
	 *
	 * @throws Exception
	 */
	public static void getMakeEntity(String outPathVal, String entityDir, Map<String, Object> root) throws Exception {
		// 自定义实体
		if (ChildWindowConstant.makeEntityModelMap.size() == 0) {
			return;
		}
		// 输出流
		for (Map.Entry<String, List<MakeEntityModel>> entry : ChildWindowConstant.makeEntityModelMap.entrySet()) {
			String makeEntityName = entry.getKey();
			List<MakeEntityModel> makeEntityModels = entry.getValue();
			for (MakeEntityModel makeEntityModel : makeEntityModels) {
				if ("List".equals(makeEntityModel.getServiceType())) {
					root.put(CodeConstant.HAS_LIST, 1);
					break;
				}
			}
			root.put(CodeConstant.MAKE_ENTITY_NAME, makeEntityName);
			root.put(CodeConstant.MAKE_ENTITY_MODELS, makeEntityModels);
			root.put(CodeConstant.MAKE_ENTITY_NAME_CN, ChildWindowConstant.makeEntityEngAndCn.get(makeEntityName));
			makCodeByTel(getTemplate(CodeFtlConstant.MAKE_ENTITY_FTL), outPathVal, entityDir, captureName(makeEntityName) + ".java", root);
			root.remove(CodeConstant.HAS_LIST);
		}
	}

	/**
	 * springboot用到的文件 yml 启动类等
	 *
	 * @throws Exception
	 */
	public static void getSpringbootCommon(String outPathVal, String resourcesDir, String mainApplicationDir,
										   String captureProjectNameVal, String mainApplicationTestDir, String mvcConfigDir, Map<String, Object> root,
										   String frameWorkVal) throws Exception {
		// 自定义实体
		if (!"springBoot".equals(frameWorkVal)) {
			return;
		}
		makCodeByTel(getTemplate(CodeFtlConstant.APPLICATION_YML_FTL), outPathVal, resourcesDir, "application.yml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MAIN_APPLICATION_FTL), outPathVal, mainApplicationDir, captureProjectNameVal + "Application.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MAIN_APPLICATION_TEST_FTL), outPathVal, mainApplicationTestDir, captureProjectNameVal + "ApplicationTests.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MVC_CONFIG_FTL), outPathVal, mvcConfigDir, "MvcConfig.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.TRANSACTION_ADVICE_CONFIG_FTL), outPathVal, mvcConfigDir, "TransactionAdviceConfig.java", root);
	}

	/**
	 * springMVC用到的文件
	 *
	 * @throws Exception
	 */
	public static void getSpringMvcCommon(String outPathVal, String resourcesDir, String projectNameVal, String htmlDir,
										  String settingsDir, String mvcConfigDir, Map<String, Object> root, String frameWorkVal) throws Exception {
		// 自定义实体
		if (!"ssm".equals(frameWorkVal)) {
			return;
		}
		String metaInfDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_METAINF_MVC, projectNameVal);
		makCodeByTel(getTemplate(CodeFtlConstant.MVC_INTERCEPTOR_FTL), outPathVal, mvcConfigDir, "MVCInterceptor.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MVC_JDBC_PROPERTIES_FTL), outPathVal, resourcesDir, "jdbc.properties", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MVC_SPRING_MVC_FTL), outPathVal, resourcesDir, "spring-mvc.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MVC_SPRING_MYBATIS_FTL), outPathVal, resourcesDir, "spring-mybatis.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.WEB_XML_FTL), outPathVal, htmlDir, "web.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.ORG_ECLIPSE_COMPONENT_FTL), outPathVal, settingsDir, "org.eclipse.wst.common.component", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MANIFESTMF_FTL), outPathVal, metaInfDir, "MANIFEST.MF", root);
	}

	/**
	 * 动态用户生成的文件（用户名密码需要连接数据库查询的情况）
	 *
	 * @throws Exception
	 */
	public static void getDynamicUser(String outPathVal, String sqlMapperDir, String serviceDir, String serviceImplDir, String daoDir, String loginModel, Map<String, Object> root) throws Exception {
		// 自定义实体
		if (!"动态用户".equals(loginModel)) {
			return;
		}
		makCodeByTel(getTemplate(CodeFtlConstant.USER_MAPPER_FTL), outPathVal, sqlMapperDir, "loginMapper.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.IUSER_SERVICE_FTL), outPathVal, serviceDir, "LoginService.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.USER_SERVICE_FTL), outPathVal, serviceImplDir, "LoginServiceImpl.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.IUSER_DAO_FTL), outPathVal, daoDir, "LoginDao.java", root);
	}

	/**
	 * 动态生成core包下的注解
	 *
	 * @throws Exception
	 */
	public static void getCoreAnnotation(String outPathVal, String coreAnnotationDir, Map<String, Object> root) throws Exception {
		makCodeByTel(getTemplate(CodeFtlConstant.LOGIN_REQUIRED_FTL), outPathVal, coreAnnotationDir, "LoginRequired.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.NO_PACK_FTL), outPathVal, coreAnnotationDir, "NoPack.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.RECORD_LOG_FTL), outPathVal, coreAnnotationDir, "RecordLog.java", root);
	}

	/**
	 * 动态生成core包下的响应体类
	 *
	 * @throws Exception
	 */
	public static void getCoreResponse(String outPathVal, String coreDir, Map<String, Object> root) throws Exception {
		makCodeByTel(getTemplate(CodeFtlConstant.RESPONSE_RESULT_FTL), outPathVal, coreDir, "ResponseResult.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.RESPONSE_STATUS_FTL), outPathVal, coreDir, "ResponseStatus.java", root);
	}

	/**
	 * 动态生成core包下的exception类
	 *
	 * @throws Exception
	 */
	public static void getCoreException(String outPathVal, String coreExceptionDir, Map<String, Object> root) throws Exception {
		makCodeByTel(getTemplate(CodeFtlConstant.BUSINESS_EXCEPTION_FTL), outPathVal, coreExceptionDir, "BusinessException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.FORBIDDEN_EXCEPTION_FTL), outPathVal, coreExceptionDir, "ForbiddenException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.HTTP_CLIENT_CONNECTION_EXCEPTION_FTL), outPathVal, coreExceptionDir, "HttpClientConnectionException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.HTTP_CLIENT_EXCEPTION_FTL), outPathVal, coreExceptionDir, "HttpClientException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.ILLEGAL_PARAMETER_EXCEPTION_FTL), outPathVal, coreExceptionDir, "IllegalParameterException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.INTERNAL_SERVER_ERROR_EXCEPTION_FTL), outPathVal, coreExceptionDir, "InternalServerErrorException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.NOT_AUTHORIZED_EXCEPTION_FTL), outPathVal, coreExceptionDir, "NotAuthorizedException.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.NOT_FOUND_EXCEPTION_FTL), outPathVal, coreExceptionDir, "NotFoundException.java", root);
	}


	/**
	 * 公共代码的生成
	 *
	 * @throws Exception
	 */
	public static void getCommonCode(String outPathVal, String projectDir, String utilDir, String themeVal,
									 String htmlDir, String webClientHtmlPath, String daoDir, String resourcesDir, String sqlMapperDir,
									 String controllerDir, String mvcConfigDir, String entityDir, String staticDir,
									 String webClientJsConfigPath, boolean authority, Map<String, Object> root) throws Exception {
		boolean ifSwagger = "是".equals(ChildWindowConstant.commonParametersModel.getIfUseSwagger());
		makCodeByTel(getTemplate(CodeFtlConstant.POM_FTL), outPathVal, projectDir, "pom.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CLASSPATH_FTL), outPathVal, projectDir, ".classpath", root);
		makCodeByTel(getTemplate(CodeFtlConstant.PROJECT_FTL), outPathVal, projectDir, ".project", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CASTUTIL_FTL), outPathVal, utilDir, "CastUtil.java", root);
		// homehtml的输出流
		if (CodeConstant.OLD_THEME.equals(themeVal)) {
			makCodeByTel(getTemplate(CodeFtlConstant.HOME_FTL), outPathVal, htmlDir, "home.html", root);
		} else {
			makCodeByTel(getTemplate(CodeFtlConstant.HOME_FTL), outPathVal, webClientHtmlPath, "home.html", root);
		}
		// welcomehtml的输出流
		if (CodeConstant.OLD_THEME.equals(themeVal)) {
			makCodeByTel(getTemplate(CodeFtlConstant.WELCOME_FTL), outPathVal, htmlDir, "welcome.html", root);
		} else {
			makCodeByTel(getTemplate(CodeFtlConstant.WELCOME_FTL), outPathVal, webClientHtmlPath, "welcome.html", root);
		}
		makCodeByTel(getTemplate(CodeFtlConstant.IBASE_DAO_FTL), outPathVal, daoDir, "BaseDao.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.EXCEL_UTIL_FTL), outPathVal, utilDir, "ExcelUtil.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.LOGBACK_FTL), outPathVal, resourcesDir, "logback.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MYBATIS_CONFIG_FTL), outPathVal, sqlMapperDir, "mybatis-config.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.USER_CONTROLLER_FTL), outPathVal, controllerDir, "LoginController.java", root);
		// loginHtml的输出流
		if (CodeConstant.OLD_THEME.equals(themeVal)) {
			makCodeByTel(getTemplate(CodeFtlConstant.LOGIN_HTML_FTL), outPathVal, htmlDir, "login.html", root);
		} else {
			makCodeByTel(getTemplate(CodeFtlConstant.LOGIN_HTML_FTL), outPathVal, webClientHtmlPath, "login.html", root);
		}
		makCodeByTel(getTemplate(CodeFtlConstant.USER_FTL), outPathVal, entityDir, authority ? "CmSysUserEntity.java" : "User.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.ALL_EXCEPTION_HANDLER_FTL), outPathVal, mvcConfigDir, "AllExceptionHandler.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CORS_CONFIG_FTL), outPathVal, mvcConfigDir, "CorsConfig.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.LOG_AOP_ASPECT_FTL), outPathVal, mvcConfigDir, "LogAopAspect.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.LOGGER_UTIL_FTL), outPathVal, utilDir, "LoggerUtil.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.PAGE_UTIL_FTL), outPathVal, utilDir, "PageUtil.java", root);
		if (ifSwagger) {
			makCodeByTel(getTemplate(CodeFtlConstant.SWAGGER_CONFIG_FTL), outPathVal, mvcConfigDir, "SwaggerConfig.java", root);
		}
		// 根据主题的不同生成的路径不同
		if (CodeConstant.OLD_THEME.equals(themeVal)) {
			makCodeByTel(getTemplate(CodeFtlConstant.CONFIG_JS_FTL), outPathVal, staticDir + "js/", "config.js", root);
		} else {
			makCodeByTel(getTemplate(CodeFtlConstant.CONFIG_JS_FTL), outPathVal, webClientJsConfigPath, "config.js", root);
		}
		makCodeByTel(getTemplate(CodeFtlConstant.COMMON_ENTITY_FTL), outPathVal, entityDir, "CommonEntity.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.PAGE_DATA_FTL), outPathVal, entityDir, "PageData.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.JACKSON_CONFIG_FTL), outPathVal, mvcConfigDir, "JacksonConfig.java", root);
	}

	/**
	 * 单表相关代码生成
	 *
	 * @throws Exception
	 */
	public static void getSingleTableCode(boolean mutiDataSource, String outPathVal, String ifJavaBean, String entityDir, String daoDir,
										  String serviceDir, String serviceImplDir, String controllerDir, String sqlMapperDir, String themeVal,
										  String htmlDir, String webClientHtmlPath, String[] tableNameArr, String dataBaseTypeVal,
										  Map<String, Object> root) throws Exception {
		if (mutiDataSource) {
			//如果配置了多数据源
			for (Map.Entry<String, DataSourceModel> modelEntry : ChildWindowConstant.dataSourceModelMap.entrySet()) {
				String dataSource = modelEntry.getKey();
				DataSourceModel sourceModel = modelEntry.getValue();
				String modelTableName = sourceModel.getTableName();
				tableNameArr = modelTableName.split("#");
				//当前数据源
				root.put(CodeConstant.CURRENT_DATA_SOURCE_NAME, dataSource);
				root.put(CodeConstant.DATA_BASE_TYPE, sourceModel.getDataBaseTypeVal());
				makeSingleTableCode(outPathVal, ifJavaBean, entityDir, daoDir, serviceDir, serviceImplDir, controllerDir, sqlMapperDir, themeVal, htmlDir, webClientHtmlPath, tableNameArr, sourceModel.getDataBaseTypeVal(),
						root, sourceModel.getCurrentTableNameAndTypes(), sourceModel.getPrimaryKeyListMap(), sourceModel.getCurrentTableCnNameMap(), sourceModel.getAllColumnMsgMap(),
						sourceModel.getColumnMsgMap(), sourceModel.getUpdateColumnMsgMap(), sourceModel.getQueryColumnMsgMap());
			}
			//恢复type
			root.put(CodeConstant.DATA_BASE_TYPE, dataBaseTypeVal);
		} else {
			makeSingleTableCode(outPathVal, ifJavaBean, entityDir, daoDir, serviceDir, serviceImplDir, controllerDir, sqlMapperDir, themeVal, htmlDir, webClientHtmlPath, tableNameArr, dataBaseTypeVal,
					root, ChildWindowConstant.currentTableNameAndTypes, ChildWindowConstant.primaryKeyListMap, ChildWindowConstant.currentTableCnNameMap, ChildWindowConstant.allColumnMsgMap,
					ChildWindowConstant.columnMsgMap, ChildWindowConstant.updateColumnMsgMap, ChildWindowConstant.queryColumnMsgMap);
		}
	}

	/**
	 * 生成单表代码
	 */
	private static void makeSingleTableCode(String outPathVal, String ifJavaBean, String entityDir, String daoDir,
											String serviceDir, String serviceImplDir, String controllerDir, String sqlMapperDir, String themeVal,
											String htmlDir, String webClientHtmlPath, String[] tableNameArr, String dataBaseTypeVal,
											Map<String, Object> root, Map<String, List<TableNameAndType>> currentTableNameAndTypes,
											Map<String, List<String>> primaryKeyListMap, Map<String, String> currentTableCnNameMap, Map<String, List<DatabaseModel>> allColumnMsgMap,
											Map<String, List<DatabaseModel>> columnMsgMap, Map<String, List<DatabaseModel>> updateColumnMsgMap, Map<String, List<DatabaseModel>> queryColumnMsgMap) throws Exception {
		for (String currentTableName : tableNameArr) {
			root.put(CodeConstant.REAL_TABLE_NAME, currentTableName);
			String captureurrentTableName = CodeWriterUtil.captureName(currentTableName);
			// 如果是JavaBean配置
			if ("JavaBean".equals(ifJavaBean)) {
				// bean的名称
				root.put(CodeConstant.ENTITY_NAME, captureurrentTableName + "Entity");
				List<TableNameAndType> tableNameAndTypes = currentTableNameAndTypes.get(currentTableName);
				root.put(CodeConstant.ENTITY_NAME_AND_TYPES, tableNameAndTypes);
			}
			root.put(CodeConstant.IDAO_NAME, captureurrentTableName + "Dao");
			root.put(CodeConstant.ISERVICE_NAME, captureurrentTableName + "Service");
			root.put(CodeConstant.SERVICE_NAME, captureurrentTableName + "ServiceImpl");
			root.put(CodeConstant.CONTROLLER_NAME, captureurrentTableName + "Controller");
			root.put(CodeConstant.CONTROLLER_PREFIX,
					captureurrentTableName.length() > 1
							? captureurrentTableName.substring(0, 1).toLowerCase() + captureurrentTableName.substring(1)
							: captureurrentTableName.substring(0, 1).toLowerCase());
			root.put(CodeConstant.TABLE_NAME, captureurrentTableName);
			List<String> primaryKeyList = primaryKeyListMap.get(currentTableName);
			String currentTableCnName = currentTableCnNameMap.get(currentTableName);
			// root.put(CodeConstant.primaryKeyList, primaryKeyList);
			root.put(CodeConstant.CURRENT_TABLE_CN_NAME, currentTableCnName);
			// 因为主键必须设置 所以所有的条件不可能为0
			List<DatabaseModel> allColumnList = allColumnMsgMap.get(currentTableName);
			List<DatabaseModel> sortAllColumnList = new ArrayList<>(allColumnList);
			if ("mysql".equals(dataBaseTypeVal)) {
				sortAllColumnList.sort((o1, o2) -> {
					if (o1.getWhereNo().compareTo(o2.getWhereNo()) == 0) {
						return 0;
					} else if (o2.getWhereNo().compareTo(o1.getWhereNo()) > 0) {
						return -1;
					} else {
						return 1;
					}
				});
			} else if ("oracle".equals(dataBaseTypeVal)) {
				sortAllColumnList.sort((o1, o2) -> {
					if (o1.getWhereNo().compareTo(o2.getWhereNo()) == 0) {
						return 0;
					} else if (o2.getWhereNo().compareTo(o1.getWhereNo()) > 0) {
						return 1;
					} else {
						return -1;
					}
				});
			}
			// sql条件排序使用
			root.put(CodeConstant.COLUMN_LIST, sortAllColumnList);
			// 页面显示使用
			List<DatabaseModel> selectColumnList = columnMsgMap.get(currentTableName);
			selectColumnList.sort((o1, o2) -> {
				if (o1.getShowNo().compareTo(o2.getShowNo()) == 0) {
					return 0;
				} else if (o2.getShowNo().compareTo(o1.getShowNo()) > 0) {
					return -1;
				} else {
					return 1;
				}
			});
			// 如果查询的个数为0 则默认查全部
			if (selectColumnList.size() == 0) {
				selectColumnList.addAll(allColumnList);
				root.put(CodeConstant.SELECT_COLUMN_LIST, allColumnList);
			} else {
				// 设置的查询字段列表
				root.put(CodeConstant.SELECT_COLUMN_LIST, selectColumnList);
			}
			List<DatabaseModel> updateColumnList = updateColumnMsgMap.get(currentTableName);
			// 如果没有配置更新，以初始展示的项目为准
			if (updateColumnList.size() == 0) {
				updateColumnList.addAll(selectColumnList);
				root.put(CodeConstant.UPDATE_COLUMN_LIST, selectColumnList);
			} else {
				root.put(CodeConstant.UPDATE_COLUMN_LIST, updateColumnList);
			}
			List<DatabaseModel> queryColumnList = queryColumnMsgMap.get(currentTableName);
			// 如果没有配置更新，以初始展示的项目为准
			if (queryColumnList.size() == 0) {
				root.put(CodeConstant.QUERY_COLUMN_LIST, selectColumnList);
			} else {
				root.put(CodeConstant.QUERY_COLUMN_LIST, queryColumnList);
			}
			List<DatabaseModel> primaryKeyModelList = new ArrayList<>();
			for (String primaryKey : primaryKeyList) {
				DatabaseModel model = new DatabaseModel();
				model.setColumnsEng(primaryKey);
				// 设置sqlParamColumnEng
				model.setSqlParamColumnEng(DataUtils.getSqlParam(primaryKey));
				primaryKeyModelList.add(model);
			}
			// 遍历主键的模型list，判断在selectColumnList中存不存在,如不存在，加入
			List<DatabaseModel> selectColumnListMapper = new ArrayList<>(selectColumnList);
			for (DatabaseModel model : primaryKeyModelList) {
				// 如果没有，添加
				if (!selectColumnListMapper.contains(model)) {
					selectColumnListMapper.add(model);
				}
				/*
				 * if (updateColumnList.contains(model)) { updateColumnList.remove(model); }
				 */
			}
			root.put(CodeConstant.PRIMARY_KEY_MODEL_LIST, primaryKeyModelList);
			root.put(CodeConstant.SELECT_COLUMN_LIST_MAPPER, selectColumnListMapper);
			// 实体类输出
			if ("JavaBean".equals(ifJavaBean)) {
				makCodeByTel(getTemplate(CodeFtlConstant.ENTITY_FTL), outPathVal, entityDir, captureurrentTableName + "Entity.java", root);
			}
			makCodeByTel(getTemplate(CodeFtlConstant.DAO_FTL), outPathVal, daoDir, captureurrentTableName + "Dao.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.ISERVICE_FTL), outPathVal, serviceDir, captureurrentTableName + "Service.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.SERVICE_FTL), outPathVal, serviceImplDir, captureurrentTableName + "ServiceImpl.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.CONTROLLER_FTL), outPathVal, controllerDir, captureurrentTableName + "Controller.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.SQL_MAPPER_FTL), outPathVal, sqlMapperDir, CodeWriterUtil.firstLower(captureurrentTableName) + "Mapper.xml", root);
			// 当前表html的输出文件
			if (CodeConstant.OLD_THEME.equals(themeVal)) {
				makCodeByTel(getTemplate(CodeFtlConstant.HTML_FTL), outPathVal, htmlDir + currentTableName + "/", "list.html", root);
				// 前后端分离主题
			} else {
				makCodeByTel(getTemplate(CodeFtlConstant.HTML_FTL), outPathVal, webClientHtmlPath + currentTableName + "/", "list.html", root);
			}
		}
	}

	/**
	 * 多表相关代码生成
	 *
	 * @throws Exception
	 */
	public static void getMutiTableCode(String dataBaseTypeVal, boolean mutiDataSource, String outPathVal, String sqlMapperDir, String serviceDir,
										String serviceImplDir, String daoDir, String controllerDir, String themeVal, String entityDir, String htmlDir,
										String webClientHtmlPath, Map<String, Object> root) throws Exception {
		if (mutiDataSource) {
			//如果配置了多数据源模式生成
			for (Map.Entry<String, DataSourceModel> modelEntry : ChildWindowConstant.dataSourceModelMap.entrySet()) {
				String dataSource = modelEntry.getKey();
				DataSourceModel sourceModel = modelEntry.getValue();
				//当前数据源
				root.put(CodeConstant.CURRENT_DATA_SOURCE_NAME, dataSource);
				root.put(CodeConstant.DATA_BASE_TYPE, sourceModel.getDataBaseTypeVal());
				makeMutiTableCode(outPathVal, sqlMapperDir, serviceDir, serviceImplDir, daoDir, controllerDir, themeVal, entityDir, htmlDir, webClientHtmlPath, root, sourceModel.getTablesQueryMap(), sourceModel.getTablesQueryEndAndCnMap());
			}
			//恢复type
			root.put(CodeConstant.DATA_BASE_TYPE, dataBaseTypeVal);
		} else {
			makeMutiTableCode(outPathVal, sqlMapperDir, serviceDir, serviceImplDir, daoDir, controllerDir, themeVal, entityDir, htmlDir, webClientHtmlPath, root, ChildWindowConstant.tablesQueryMap, ChildWindowConstant.tablesQueryEndAndCnMap);
		}
	}

	/**
	 * 生成多表的代码
	 */
	private static void makeMutiTableCode(String outPathVal, String sqlMapperDir, String serviceDir,
										  String serviceImplDir, String daoDir, String controllerDir, String themeVal, String entityDir, String htmlDir,
										  String webClientHtmlPath, Map<String, Object> root, Map<String, Map<String, TablesQueryModel>> tablesQueryMap, Map<String, String> tablesQueryEndAndCnMap) throws Exception {
		// 多表配置生成文件
		for (Map.Entry<String, Map<String, TablesQueryModel>> methodEntry : tablesQueryMap.entrySet()) {
			// 当前模块英文名
			String currentMutiEng = methodEntry.getKey();
			// 当前模块中文名
			String currentMutiCn = tablesQueryEndAndCnMap.get(currentMutiEng);
			root.put(CodeConstant.CURRENT_MUTI_ENG, currentMutiEng);
			String capCurrentMutiEng = CodeWriterUtil.captureName(currentMutiEng);
			root.put(CodeConstant.CAP_CURRENT_MUTI_ENG, capCurrentMutiEng);
			root.put(CodeConstant.CURRENT_MUTI_CN, currentMutiCn);
			Map<String, TablesQueryModel> methodMap = methodEntry.getValue();
			// 方法的map
			root.put(CodeConstant.CURRENT_METHOD_MAP, methodMap);
			//生成java代码
			makCodeByTel(getTemplate(CodeFtlConstant.MUTI_TABLE_SQL_MAPPER_FTL), outPathVal, sqlMapperDir, CodeWriterUtil.firstLower(capCurrentMutiEng) + "MutiSqlMapper.xml", root);
			makCodeByTel(getTemplate(CodeFtlConstant.IMUTI_TABLE_DAO_FTL), outPathVal, daoDir, capCurrentMutiEng + "MutiDao.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.IMUTI_TABLE_SERVICE_FTL), outPathVal, serviceDir, capCurrentMutiEng + "MutiService.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.MUTI_TABLE_SERVICE_FTL), outPathVal, serviceImplDir, capCurrentMutiEng + "MutiServiceImpl.java", root);
			makCodeByTel(getTemplate(CodeFtlConstant.MUTI_TABLE_CONTROLLER_FTL), outPathVal, controllerDir, capCurrentMutiEng + "MutiController.java", root);
			// 遍历当前模块的所有方法 一个方法对应一个entity和一个html
			for (Map.Entry<String, TablesQueryModel> method : methodMap.entrySet()) {
				// 当前方法名
				String methodName = method.getKey();
				TablesQueryModel tablesQueryModel = method.getValue();
				// 当前方法中文名
				String methodNameCn = tablesQueryModel.getMethodName_cn();
				// 当前方法实体名 首字母大写
				String entityName = CodeWriterUtil.captureName(tablesQueryModel.getEntityName());
				// 当前方法实体中文名
				String entityNameCn = tablesQueryModel.getEntityName_cn();
				List<TableFiledModel> tableFiledModels = tablesQueryModel.getTableFiledModels();
				List<TableConditionModel> tableConditionModels = tablesQueryModel.getTableConditionModels();
				// entity的集合
				List<EntityFieldModel> entityFieldList = new ArrayList<>();
				for (TableFiledModel model : tableFiledModels) {
					EntityFieldModel entityFieldModel = new EntityFieldModel();
					entityFieldModel.setFieldName(model.getAnotherFiledName());
					entityFieldModel.setFieldName_cn(model.getFiledText_cn());
					entityFieldModel.setFieldType(model.getFiledType());
					entityFieldModel.setCompareText("");
					entityFieldList.add(entityFieldModel);
				}
				for (TableConditionModel model : tableConditionModels) {
					EntityFieldModel entityFieldModel = new EntityFieldModel();
					entityFieldModel.setFieldName(model.getAnotherTableName() + "_" + model.getFiled_eng());
					entityFieldModel.setFieldName_cn(model.getFiled_cn());
					entityFieldModel.setFieldType(model.getServiceType());
					entityFieldModel.setCompareText(model.getCompareText());
					if (!entityFieldList.contains(entityFieldModel) && "".equals(model.getUnchangeValue())) {
						entityFieldList.add(entityFieldModel);
					}
				}
				root.put(CodeConstant.CURRENT_MUTI_METHOD_ENG, methodName);
				root.put(CodeConstant.CURRENT_MUTI_METHOD_CN, methodNameCn);
				root.put(CodeConstant.CURRENT_MUTI_ENTITY_NAME, entityName + "Muti");
				root.put(CodeConstant.CURRENT_MUTI_ENTITY_NAME_CN, entityNameCn);
				root.put(CodeConstant.TABLE_FILED_MODELS, tableFiledModels);
				root.put(CodeConstant.TABLE_CONDITION_MODELS, tableConditionModels);
				root.put(CodeConstant.ENTITY_FILED_MODELS, entityFieldList);
				// 一个方法一个html
				if (CodeConstant.OLD_THEME.equals(themeVal)) {
					makCodeByTel(getTemplate(CodeFtlConstant.MUTI_TABLE_HTML_FTL), outPathVal, htmlDir + currentMutiEng + "Muti/", methodName + "List.html", root);
				} else {
					makCodeByTel(getTemplate(CodeFtlConstant.MUTI_TABLE_HTML_FTL), outPathVal, webClientHtmlPath + currentMutiEng + "Muti/", methodName + "List.html", root);
				}
				makCodeByTel(getTemplate(CodeFtlConstant.MUTI_TABLE_ENTITY_FTL), outPathVal, entityDir, entityName + "Muti.java", root);
			}
		}
	}

	/**
	 * 生成setting文件夹下的代码（eclipse用户使用）
	 */
	public static void getSettingCode(Map<String, Object> root, String outPathVal, String frameWorkVal, String settingsDir) {
		if (isNotALL(root)) {
			return;
		}
		try {
			String realSettingDir = FreeOutUtil.checkAndMakeDir(outPathVal + settingsDir);
			File mvcSettingsZip = new File(Constant.mvcSettingsZip);
			File settingsZip = new File(Constant.settingsZip);
			if ("ssm".equals(frameWorkVal)) {
				if (!mvcSettingsZip.exists()) {
					mvcSettingsZip = HttpDownloadUtil.downloadFile(Constant.downMvcSettingsZipNet, Constant.modelFiles);
				}
				ZipUtils.unZip(mvcSettingsZip, realSettingDir, Constant.ZIP_PWD);
			}
			if ("springBoot".equals(frameWorkVal)) {
				if (!settingsZip.exists()) {
					settingsZip = HttpDownloadUtil.downloadFile(Constant.downSettingsZipNet, Constant.modelFiles);
				}
				ZipUtils.unZip(settingsZip, realSettingDir, Constant.ZIP_PWD);
			}
		} catch (Exception e) {
			throw new RuntimeException("生成配置文件setting时出错！可能是网络问题导致的，请重试！");
		}
	}

	/**
	 * 生成static文件夹下的代码
	 */
	public static void getStaticCode(Map<String, Object> root, String outPathVal, String themeVal, String staticDir, String webClientPath) {
		if (isNotALL(root)) {
			return;
		}
		try {
			if (CodeConstant.OLD_THEME.equals(themeVal)) {
				String realStaticDir = FreeOutUtil.checkAndMakeDir(outPathVal + staticDir);
				File staticZip = new File(Constant.staticZip);
				ZipUtils.unZip(staticZip, realStaticDir, Constant.ZIP_PWD);
				// 如果是前后端分离响应式项目
			} else if (CodeConstant.H_ADMIN_THEME.equals(themeVal)) {
				String realWebClientPath = FreeOutUtil.checkAndMakeDir(outPathVal + webClientPath);
				File webClientZip = new File(Constant.webClientZip);
				ZipUtils.unZip(webClientZip, realWebClientPath, Constant.ZIP_PWD);
			}
		} catch (Exception e) {
			throw new RuntimeException("生成静态资源文件时出错！可能是网络问题导致的，请重试！");
		}
	}

	/**
	 * 生成ojdbc的lib文件夹
	 */
	public static void getOjdbcCode(boolean mutiDataSource, Map<String, Object> root, String outPathVal, String frameWorkVal, String dataBaseTypeVal,
									String projectNameVal) {
		if (isNotALL(root)) {
			return;
		}
		// 如果是oracle,sqlserver或者多数据源模式，需要添加ojdbc支持
		if ("oracle".equals(dataBaseTypeVal) || "sqlserver".equals(dataBaseTypeVal) || mutiDataSource) {
			// 下载lib.zip文件到项目路径下 oracle sqlserver 的驱动
			String libDir = null;
			if ("ssm".equals(frameWorkVal)) {
				libDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_LIB_MVC, projectNameVal);
			}
			if ("springBoot".equals(frameWorkVal)) {
				libDir = FreeOutUtil.setProjectName(Constant.FREE_OUT_PATH_LIB, projectNameVal);
			}
			try {
				String realLibDir = FreeOutUtil.checkAndMakeDir(outPathVal + libDir);
				File libZip = new File(Constant.libZip);
				if (!libZip.exists()) {
					libZip = HttpDownloadUtil.downloadFile(Constant.downLibZipNet, Constant.modelFiles);
				}
				ZipUtils.unZip(libZip, realLibDir, Constant.ZIP_PWD);
			} catch (Exception e) {
				throw new RuntimeException("生成lib文件夹时出错！可能是网络问题导致的，请重试！");
			}
		}
	}


	/**
	 * 生成权限相关代码
	 *
	 * @param outPathVal
	 * @param utilDir
	 * @param themeVal
	 * @param htmlDir
	 * @param webClientHtmlPath
	 * @param daoDir
	 * @param sqlMapperDir
	 * @param controllerDir
	 * @param entityDir
	 * @param constantDir
	 * @param root
	 */
	public static void makeAuthCode(String outPathVal, String utilDir, String themeVal, String htmlDir, String webClientHtmlPath, String daoDir, String sqlMapperDir, String controllerDir, String serviceDir, String serviceImplDir, String entityDir, String constantDir, String coreAnnotationDir, String coreValidatesDir, String dtoDir, Map<String, Object> root) throws Exception {
		makCodeByTel(getTemplate(CodeFtlConstant.MOVE_TYPE_FTL), outPathVal, constantDir, "MoveType.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.YES_OR_NO_FTL), outPathVal, constantDir, "YesOrNo.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_BUTTON_CONTROLLER_FTL), outPathVal, controllerDir, "CmSysButtonController.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_CONTROLLER_FTL), outPathVal, controllerDir, "CmSysMenuController.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_CONTROLLER_FTL), outPathVal, controllerDir, "CmSysRoleController.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_CONTROLLER_FTL), outPathVal, controllerDir, "CmSysUserController.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.EXTERNAL_FIELD_FTL), outPathVal, coreAnnotationDir, "ExternalField.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.ADD_FTL), outPathVal, coreValidatesDir, "Add.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.UPDATE_FTL), outPathVal, coreValidatesDir, "Update.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_BUTTON_DAO_FTL), outPathVal, daoDir, "CmSysButtonDao.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_DAO_FTL), outPathVal, daoDir, "CmSysMenuDao.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_DAO_FTL), outPathVal, daoDir, "CmSysRoleDao.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_DAO_FTL), outPathVal, daoDir, "CmSysUserDao.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.NODE_MOVE_DTO_FTL), outPathVal, dtoDir, "NodeMoveDto.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_BUTTON_ENTITY_FTL), outPathVal, entityDir, "CmSysButtonEntity.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_ENTITY_FTL), outPathVal, entityDir, "CmSysMenuEntity.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_BUTTON_ENTITY_FTL), outPathVal, entityDir, "CmSysRoleButtonEntity.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_ENTITY_FTL), outPathVal, entityDir, "CmSysRoleEntity.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_MENU_ENTITY_FTL), outPathVal, entityDir, "CmSysRoleMenuEntity.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_BUTTON_MAPPER_FTL), outPathVal, sqlMapperDir, "cmSysButtonMapper.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_MAPPER_FTL), outPathVal, sqlMapperDir, "cmSysMenuMapper.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_MAPPER_FTL), outPathVal, sqlMapperDir, "cmSysRoleMapper.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_MAPPER_FTL), outPathVal, sqlMapperDir, "cmSysUserMapper.xml", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_BUTTON_SERVICE_FTL), outPathVal, serviceDir, "CmSysButtonService.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_SERVICE_FTL), outPathVal, serviceDir, "CmSysMenuService.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_SERVICE_FTL), outPathVal, serviceDir, "CmSysRoleService.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_SERVICE_FTL), outPathVal, serviceDir, "CmSysUserService.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_BUTTON_SERVICE_IMPL_FTL), outPathVal, serviceImplDir, "CmSysButtonServiceImpl.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_SERVICE_IMPL_FTL), outPathVal, serviceImplDir, "CmSysMenuServiceImpl.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_SERVICE_IMPL_FTL), outPathVal, serviceImplDir, "CmSysRoleServiceImpl.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_SERVICE_IMPL_FTL), outPathVal, serviceImplDir, "CmSysUserServiceImpl.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.MD5_UTIL_FTL), outPathVal, utilDir, "Md5Util.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.SESSION_UTIL_FTL), outPathVal, utilDir, "SessionUtil.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.SNOWFLAKE_ID_WORKER_FTL), outPathVal, utilDir, "SnowflakeIdWorker.java", root);
		if (CodeConstant.OLD_THEME.equals(themeVal)) {
			makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_HTML_FTL), outPathVal, htmlDir + "cmSysMenu/", "list.html", root);
			makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_HTML_FTL), outPathVal, htmlDir + "cmSysRole/", "list.html", root);
			makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_HTML_FTL), outPathVal, htmlDir + "cmSysUser/", "list.html", root);
		} else {
			makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_MENU_HTML_FTL), outPathVal, webClientHtmlPath + "cmSysMenu/", "list.html", root);
			makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_ROLE_HTML_FTL), outPathVal, webClientHtmlPath + "cmSysRole/", "list.html", root);
			makCodeByTel(getTemplate(CodeFtlConstant.CM_SYS_USER_HTML_FTL), outPathVal, webClientHtmlPath + "cmSysUser/", "list.html", root);
		}
	}

	/**
	 * 多数据源代码生成
	 *
	 * @param frameWorkVal
	 */
	public static void getMutiSourceCode(String outPathVal, String mutidatasourceDir, String frameWorkVal, Map<String, Object> root) throws Exception {
		makCodeByTel(getTemplate(CodeFtlConstant.DATA_SOURCE_TYPE), outPathVal, mutidatasourceDir, "DataSourceType.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.DB_TYPE), outPathVal, mutidatasourceDir, "DBType.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.DYNAMIC_DATA_SOURCE), outPathVal, mutidatasourceDir, "DynamicDataSource.java", root);
		makCodeByTel(getTemplate(CodeFtlConstant.DYNAMIC_DATA_SOURCE_ASPECT), outPathVal, mutidatasourceDir, "DynamicDataSourceAspect.java", root);
		if ("springBoot".equals(frameWorkVal)) {
			makCodeByTel(getTemplate(CodeFtlConstant.DYNAMIC_DATA_SOURCE_CONFIG), outPathVal, mutidatasourceDir, "DynamicDataSourceConfig.java", root);
		}
		makCodeByTel(getTemplate(CodeFtlConstant.DYNAMIC_DATA_SOURCE_HOLDER), outPathVal, mutidatasourceDir, "DynamicDataSourceHolder.java", root);
	}

	/**
	 * 根据模板生成代码文件
	 */
	private static void makCodeByTel(Template template, String outPathVal, String dir, String fileName, Map<String, Object> root) throws Exception {
		//如果都不满足生成条件
		if (isNotALL(root) && !isController(template, root) && !isService(template, root) && !isDao(template, root) && !isEntity(template, root) && !isView(template, root)) {
			return;
		}
		Writer out = new OutputStreamWriter(
				new FileOutputStream(
						FreeOutUtil.checkAndMakeDir(outPathVal + dir) + fileName),
				StandardCharsets.UTF_8);
		template.process(root, out);
		out.flush();
		out.close();
	}

	/**
	 * 是否生全部
	 *
	 * @return
	 */
	private static boolean isNotALL(Map<String, Object> root) {

		boolean isController = (boolean) root.get(CodeConstant.IS_CONTROLLER);
		boolean isService = (boolean) root.get(CodeConstant.IS_SERVICE);
		boolean isDao = (boolean) root.get(CodeConstant.IS_DAO);
		boolean isEntity = (boolean) root.get(CodeConstant.IS_ENTITY);
		boolean isView = (boolean) root.get(CodeConstant.IS_VIEW);
		//有一个选了等于没有全选
		return isController || isService || isDao || isEntity || isView;
	}

	/**
	 * 是否生controller
	 *
	 * @return
	 */
	private static boolean isController(Template template, Map<String, Object> root) {
		String templateName = template.getName();
		boolean isController = (boolean) root.get(CodeConstant.IS_CONTROLLER);
		return isController && (templateName.contains(CodeFtlConstant.CONTROLLER_FTL) || templateName.contains(CodeFtlConstant.MUTI_TABLE_CONTROLLER_FTL));
	}

	/**
	 * 是否生service
	 *
	 * @return
	 */
	private static boolean isService(Template template, Map<String, Object> root) {
		String templateName = template.getName();
		boolean isService = (boolean) root.get(CodeConstant.IS_SERVICE);
		return isService && (templateName.contains(CodeFtlConstant.SERVICE_FTL) || templateName.contains(CodeFtlConstant.ISERVICE_FTL) || templateName.contains(CodeFtlConstant.IMUTI_TABLE_SERVICE_FTL) || templateName.contains(CodeFtlConstant.MUTI_TABLE_SERVICE_FTL));
	}

	/**
	 * 是否生service
	 *
	 * @return
	 */
	private static boolean isDao(Template template, Map<String, Object> root) {
		String templateName = template.getName();
		boolean isDao = (boolean) root.get(CodeConstant.IS_DAO);
		return isDao && (templateName.contains(CodeFtlConstant.DAO_FTL) || templateName.contains(CodeFtlConstant.IMUTI_TABLE_DAO_FTL) || templateName.contains(CodeFtlConstant.SQL_MAPPER_FTL) || templateName.contains(CodeFtlConstant.MUTI_TABLE_SQL_MAPPER_FTL));
	}

	/**
	 * 是否生entity
	 *
	 * @return
	 */
	private static boolean isEntity(Template template, Map<String, Object> root) {
		String templateName = template.getName();
		boolean isEntity = (boolean) root.get(CodeConstant.IS_ENTITY);
		return isEntity && (templateName.contains(CodeFtlConstant.ENTITY_FTL) || templateName.contains(CodeFtlConstant.MUTI_TABLE_ENTITY_FTL) || templateName.contains(CodeFtlConstant.MAKE_ENTITY_FTL) || templateName.contains(CodeFtlConstant.COMMON_ENTITY_FTL));
	}

	/**
	 * 是否生view
	 *
	 * @return
	 */
	private static boolean isView(Template template, Map<String, Object> root) {
		String templateName = template.getName();
		boolean isView = (boolean) root.get(CodeConstant.IS_VIEW);
		return isView && (templateName.contains(CodeFtlConstant.HTML_FTL) || templateName.contains(CodeFtlConstant.MUTI_TABLE_HTML_FTL));
	}

	/**
	 * 判断当前操作系统
	 */
	public static String getSystemType() {
		String osName = System.getProperty("os.name");
		if (osName.startsWith(Constant.MAC_OS)) {
			return Constant.MAC_OS;
		} else if (osName.startsWith("Windows")) {
			return Constant.WINDOWS;
		} else {
			return null;
		}
	}

	/**
	 * 特殊字符过滤
	 *
	 * @param str
	 * @return
	 */
	public static String spStrFilter(String str) {
		// 清除掉所有特殊字符
		String regEx = "[-`~!@#$%^&*()+=|{}':;,\\[\\].<>/?！￥…（）—【】‘；：”“’。，、？]";
		Pattern p = Pattern.compile(regEx);
		Matcher m = p.matcher(str);
		return m.replaceAll("").trim();
	}


}
